package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.jsonwebtoken.Claims;
import org.example.domain.Comment;
import org.example.domain.User;
import org.example.filter.aop.CheckToken;
import org.example.mapper.CommentMapper;
import org.example.param.CommentAddParam;
import org.example.service.CommentService;
import org.example.service.UserService;
import org.example.utils.HttpCode;
import org.example.utils.JwtUtil;
import org.example.utils.RequestContextUtil;
import org.example.utils.Result;
import org.example.vo.CommentUserVo;
import org.example.vo.CommentVo;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

@Service
public class CommentServiceImpl implements CommentService {
    @Resource
    private CommentMapper commentMapper;
    @Resource
    private UserService userService;

    /**
     * 评论有着多级,
     * 先查出第一级
     *
     * @param articleId
     * @return
     */
    @Override
    public Result findCommentByArticle(Long articleId) {
        if (articleId == null){
            return Result.fail(HttpCode.PARAM_ERROR);
        }
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getArticleId,articleId);
        wrapper.eq(Comment::getLevel,1);
        wrapper.orderByDesc(Comment::getCreateDate);
        Page<Comment> commentPage = commentMapper.selectPage(new Page<>(1, 6), wrapper);
        List<CommentVo> commentVoPage = copyCommentVo(commentPage.getRecords());
        //
        Page<CommentVo> result = new Page<>();
        result.setRecords(commentVoPage);
        result.setTotal(commentPage.getTotal());
        return Result.success(result);
    }

    @Override
    @CheckToken
    public Result delete(Long id) {
        String token = RequestContextUtil.getRequest().getHeader("Authorization");
        if (!StringUtils.hasText(token) || id == null){
            return Result.fail(HttpCode.PARAM_ERROR);
        }
        Long userId = Long.valueOf(JwtUtil.decryptToken(token).getId());
        if (userId == null){
            return Result.fail(HttpCode.TOKEN_ERROR);
        }
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getAuthorId,userId);
        wrapper.eq(Comment::getId,id);
        int total = commentMapper.delete(wrapper);
        if (total == 0){
            return Result.fail(HttpCode.DELETE_ERROR);
        }
        wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getParentId,id);
        commentMapper.delete(wrapper);
        return Result.success();
    }

    @Override
    @CheckToken()
    public Result add(CommentAddParam commentAddParam) {
        String token = RequestContextUtil.getRequest().getHeader("Authorization");
        if (!StringUtils.hasText(token)){
            return Result.fail(HttpCode.NO_LOGIN);
        }
        Claims claims = JwtUtil.decryptToken(token);
        if (claims == null){
            return Result.fail(HttpCode.TOKEN_ERROR);
        }
        Comment comment = Comment.builder()
                .articleId(commentAddParam.getArticleId())
                .authorId(Long.valueOf(claims.getId()))
                .content(commentAddParam.getContent())
                .parentId(commentAddParam.getParentId())
                .level(commentAddParam.getLevel() != null ? commentAddParam.getLevel() : commentAddParam.getParentId()!=null ? 2 : 1)
                .createDate(System.currentTimeMillis())
                .build();

        int total = commentMapper.insert(comment);
        if (total == 0){
            return Result.fail(HttpCode.INSERT_ERROR);
        }
        return Result.success();
    }

    /**
     * 查找二级的评论
     * @param comments
     * @return
     */
    private final List<CommentVo> copyCommentVo(List<Comment> comments){
        List<CommentVo> commentVos = new LinkedList<>();
        comments.forEach( comment -> {
            User user = (User) userService.findUserById(comment.getAuthorId()).getData();
            // 找到作者
            CommentUserVo commentUserVo = null;
            if (user!=null){
                commentUserVo = CommentUserVo.builder()
                        .id(user.getId())
                        .account(user.getAccount())
                        .avatar(user.getAvatar())
                        .build();
            }
            // 找到子评论
            List<CommentVo> child = new ArrayList<>();
            if (comment.getLevel() == 1){
                LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(Comment::getParentId,comment.getId());
                wrapper.eq(Comment::getLevel,2);
                List<Comment> commentList = commentMapper.selectList(wrapper);
                child = copyCommentVo(commentList);
            }
            // 构造
            CommentVo commentVo = CommentVo.builder()
                    .id(comment.getId())
                    .content(comment.getContent())
                    .createDate(comment.getCreateDate())
                    .commentUserVo(commentUserVo)
                    .child(child)
                    .build();
            // 添加
            commentVos.add(commentVo);
        });
        return commentVos;
    }

}
